clear; close all; clc; 

load ../data/music_dataset.mat
addpath 'CV/' 'DT/' 'Lyrics_Kernel/' 'SVM/libsvm/'

[Xt_lyrics] = make_lyrics_sparse(train, vocab);
[Xq_lyrics] = make_lyrics_sparse(quiz, vocab);

Yt = zeros(numel(train), 1);
for i=1:numel(train)
    Yt(i) = genre_class(train(i).genre);
end

Xt_audio = make_audio(train);
Xq_audio = make_audio(quiz);

%% Run stemmer on the example matrices 

Xt_lyrics = stemmer(Xt_lyrics,vocab);
Xq_lyrics = stemmer(Xq_lyrics,vocab);
fprintf('Stemming Complete \n');

%% Use CV to pick best depth for decision tree for Audio

params = (1:1:10)'; 

%cross-validate to find best depth 
opt_depth_dt = cv_wrapper_dt( Xt_audio, Yt, params); 

%% Use CV to pick best k for knn

params= (1:1:15)'; 

clip = 1000;
ind = randperm(clip);
X = Xt_lyrics(ind,:);
Y = Yt(ind,:);

[opt_k error_vect std_vect] = cv_wrapper(X, Y, params, 'knn', 'intersection');

save opt_k

%% Use CV to pick best C for SVM

%params = 10.^[-10:2:4]';
%liblinear_params = (0.001:0.005:0.02)';
params = [0.001 0.01 0.1 1 10 100 500 1000 5000 10000]';

%scale features to [0,1] (from libsvm)
Xt_lyrics = (Xt_lyrics - repmat(min(Xt_lyrics,[],1),size(Xt_lyrics,1),1))* ...
    spdiags(1./(max(Xt_lyrics,[],1)-min(Xt_lyrics,[],1))',0,size(Xt_lyrics,2),size(Xt_lyrics,2));

[opt_c error_vect std_vect] = cv_wrapper( Xt_lyrics, Yt, params, 'svm', 'intersection');

save opt_c

%{
%Plotting SVM cv error data
figure(1)
set(gca,'fontsize',18);
set(gcf,'color','w');

semilogx(params,error_vect(:,1),'-ob','linewidth',2);
hold on;grid on;
semilogx(params,error_vect_stem(:,1),'-or','linewidth',2);
semilogx(params,error_vect_scale(:,1),'-og','linewidth',2);
semilogx(params,error_vect_stem_scale(:,1),'-ok','linewidth',2);
xlabel('C Parameter Values');
ylabel('CV Error (0-1) (from libsvm)');
title('CV Error, SVM with Intersection Kernel');
legend('Normal Lyrics','Stemmed Lyrics','Lyric Features Re-scaled to [0,1]','Stemmed and Scaled Lyrics');
%}

%% SVM submission

%scale features to [0,1] (from libsvm)
Xt_lyrics = (Xt_lyrics - repmat(min(Xt_lyrics,[],1),size(Xt_lyrics,1),1))* ...
    spdiags(1./(max(Xt_lyrics,[],1)-min(Xt_lyrics,[],1))',0,size(Xt_lyrics,2),size(Xt_lyrics,2));

%Xq_lyrics = (Xq_lyrics - repmat(min(Xq_lyrics,[],1),size(Xq_lyrics,1),1))* ...
%    spdiags(1./(max(Xq_lyrics,[],1)-min(Xq_lyrics,[],1))',0,size(Xq_lyrics,2),size(Xq_lyrics,2));
load('scale_factors.mat');
Xq_lyrics = (Xq_lyrics - repmat(scale_min,size(Xq_lyrics,1),1))* ...
    spdiags(1./(scale_max-scale_min)',0,size(Xq_lyrics,2),size(Xq_lyrics,2));


kernel = kernel_intersection(Xt_lyrics,Xt_lyrics);

train_struct = svmtrain(Yt, [(1:size(kernel,1))' kernel],...
    sprintf('-t 4 -b 1 -c %g', 1));

Ktest = kernel_intersection(Xt_lyrics, Xq_lyrics);

randomshit = repmat((1:10)',floor(size(Xq_lyrics,1)/10),1);
randomshit = [randomshit; ones(size(Xq_lyrics,1)-10*floor(size(Xq_lyrics,1)/10),1)];

[~, ~, probabilities] = svmpredict(randomshit, ...
    [(1:size(Ktest,1))' Ktest], train_struct, '-b 1');

ordered_prob = zeros(size(probabilities)); 
ordered_prob(:,train_struct.Label) = probabilities; 

ranks = get_ranks(ordered_prob);

%% Get and save average scaling for final_prediction

scale_min = min([Xt_lyrics; Xq_lyrics],[],1);
scale_max = max([Xt_lyrics; Xq_lyrics],[],1);

save('scale_factors.mat','scale_min','scale_max');
%sample scaling for make_final_prediction.m
%example = (example - repmat(scale_min,size(example,1),1))* ...
%    spdiags(1./(scale_max-scale_min)',0,size(example,2),size(example,2));



%% Run algorithm
ranks = predict_genre(Xt_lyrics, Xq_lyrics, ...
                      Xt_audio, Xq_audio, ...
                      Yt);

%% Save results to a text file for submission
save('-ascii', 'submit.txt', 'ranks');

